package hu.plusone.fakecommander.util.picture;

import hu.plusone.fakecommander.util.Packer;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import javax.imageio.ImageIO;
import org.apache.commons.io.IOUtils;

public class PicturePacker implements Packer {

    private static final byte[] HEADER = "<<<<PACKER HEADER>>>>".getBytes();

    private RenderedImage getRandomImageDetail() {
        return new BufferedImage(400, 300, BufferedImage.TYPE_INT_RGB);
    }

    private int findFileOffset(byte[] data) {
        for (int i = 0; i < data.length; i++) {
            boolean isHeader = true;
            for (int j = 0; j < HEADER.length; j++) {
                int checkedOffset = i + j;
                if (checkedOffset >= data.length) {
                    return -1;
                }
                byte headerByte = HEADER[j];
                byte match = data[checkedOffset];
                if (headerByte != match) {
                    isHeader = false;
                    i = checkedOffset;
                    break;
                }
            }
            if (isHeader) {
                return i + HEADER.length;
            }
        }
        return -1;
    }

    public void pack(InputStream is, OutputStream os) {
        try {
            ImageIO.write(getRandomImageDetail(), "jpg", os);
            IOUtils.write(HEADER, os);
            IOUtils.copy(is, os);
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }

    public void unPack(InputStream is, OutputStream os) {
        try {
            byte[] data = IOUtils.toByteArray(is);
            int offset = findFileOffset(data);
            IOUtils.write(Arrays.copyOfRange(data, offset, data.length), os);
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }

}
